/*
 * COPYRIGHT:	2010 Christopher Smith, licenced under the GNU GPL v2; see COPYING in the top level directory
 * PROJECT:		sdedit
 * FILE:		sdedit struct.h
 * PURPOSE:		sdedit structure, enum and constant definitons common to both C and C++
 *				
 */

struct MSG_PRE_PROCESS_OPTIONS
{
	HACCEL AcceleratorTable;
	BOOLEAN ProcessDialog;
	BOOLEAN NoDispatch;
};

enum DIALOG_NOTIFY_OPERATION
{
	DN_CLOSE_OK = 1,
	DN_CLOSE_CANCEL,
	DN_CLOSE_MAX = 0xFFFF,
	DN_APPLY,
	DN_QUERY_INHERITANCE,
	DN_QUERY_DEFAULT
};

typedef ULONG_PTR (CALLBACK *DIALOG_CALLBACK_PROC)(PVOID Context, DIALOG_NOTIFY_OPERATION Operation, ULONG_PTR Data);

struct STANDARD_ACE
{
	SID SidStart[1];
};

struct OBJECT_ACE
{
    ULONG Flags;
	//then
	//GUID ObjectType if present
	//GUID ObjectInhType if present
	//SID Sid if present
	UCHAR Body[1];
};

struct NT_ACE_HEADER
{
	BYTE Type;
	BYTE Flags;
	WORD Size;
	ACCESS_MASK Mask;
};

struct NT_ACE
{
	BYTE Type;
	BYTE Flags;
	WORD Size;
	ACCESS_MASK Mask;
	union
	{
		UCHAR Body[1];
		STANDARD_ACE Standard;
		OBJECT_ACE Object;
	};	
};

struct SDE_ACE_HEADER
{
	UCHAR Revision;
	UCHAR Type;
	USHORT Flags;
	USHORT Size;
	USHORT Source;
	ACCESS_MASK Mask;
};

struct ACE
{
	UCHAR Revision;
	UCHAR Type;
	USHORT Flags;
	USHORT Size;
	USHORT Source;
	ACCESS_MASK Mask;
	union
	{
		UCHAR Body[1];
		STANDARD_ACE Standard;
		OBJECT_ACE Object;
	};
};

//ACE.Revision values
static const UCHAR ACE_REVISION_NT_1			= 0x01; //note that MS_1 ACEs don't store a revision; only used for conversion functions
static const UCHAR ACE_REVISION_SDEDIT_1		= 0x02;

//ACE.Flags flags
static const USHORT ACE_FLAG_OBJECT_INHERIT		= 0x0001; //lower byte of flags is the same for NT_ACE's Flags
static const USHORT ACE_FLAG_CONTAINER_INHERIT	= 0x0002;
static const USHORT ACE_FLAG_NO_PROPAGATE		= 0x0004;
static const USHORT ACE_FLAG_INHERIT_ONLY		= 0x0008;
static const USHORT ACE_FLAG_INHERITED			= 0x0010;
static const USHORT ACE_FLAG_INH_SOURCE_KNOWN	= 0x0100;
static const USHORT ACE_FLAG_INH_SOURCE_MINONLY	= 0x0200;
static const USHORT ACE_FLAG_INH_INVALID		= 0x0400;

//ACL_AND_STATE.State flags
static const ULONG ACL_FLAG_CHANGED				= 0x00000001;//the ACL has changed
static const ULONG ACL_FLAG_PRESENT				= 0x00000002;//the ACL is indeed present
static const ULONG ACL_FLAG_READONLY			= 0x00000004;//the source reports that the ACL cannot be changed
static const ULONG ACL_FLAG_DEFAULTED			= 0x00000008;//the ACL comes from a default source
static const ULONG ACL_FLAG_PROTECTED			= 0x00000010;//ACL protected from inheriting auto-inherit ACEs
static const ULONG ACL_FLAG_AUTO_INHERIT		= 0x00000020;//similar to both SE_?ACL_INHERITED and SE_?ACL_INHERIT_REQ
static const ULONG ACL_FLAG_UNTRUSTED			= 0x00000040;//original source of ACL was untrusted
static const ULONG ACL_FLAG_AUDITFLAG_SUPPORT	= 0x00000080;//audit success and failure ACE flags supported
static const ULONG ACL_FLAG_MERGE_UNPROTECT		= 0x00000100;//override+clear protected flag while merging with child entries
static const ULONG ACL_FLAG_MERGE_FULL_CTRL		= 0x00000200;//full auto-inh method control supported (i.e. SdMerge::MergeTreeEditState())
static const ULONG ACL_FLAG_MERGE_CANON_CTRL	= 0x00000400;//canonical control, i.e. either inh only or inh last
static const ULONG ACL_FLAG_AUTO_INH_SOURCES	= 0x00000800;//auto-inherited ACEs can note their source
static const ULONG ACL_FLAG_DEFAULT_AVAILABLE	= 0x00001000;//a default ACL is available
static const ULONG ACL_FLAG_LABEL_ACL			= 0x00002000;//an ACL containing mandatory labels
static const UCHAR ACL_MERGE_MODE_SHIFT			= 0x10;//shift applied to bits in acl state
static const ULONG ACL_MERGE_MODE_BITS			= 0x000F0000;//bits used by merge mode (16 possible)
static const ULONG ACL_MERGE_MODE_NONE			= 0x00000000;//don't do any merging
static const ULONG ACL_MERGE_MODE_INH_NONE		= 0x00010000;//don't inherit any ACEs (even if they could be)
static const ULONG ACL_MERGE_MODE_INH_ONLY		= 0x00020000;//discard direct entries, propogate only inherited
static const ULONG ACL_MERGE_MODE_INH_LAST		= 0x00030000;//put inherited entries after direct entries (canonical ordering)
static const ULONG ACL_MERGE_MODE_INH_FIRST		= 0x00040000;//put inherited entries before direct
static const ULONG ACL_MERGE_MODE_DENY_FIRST	= 0x00050000;//put deny entries first, regardless of being inherited or not
static const ULONG ACL_MERGE_MODE_MAX			= 0x00050000;//maximum merge mode

//SID_AND_STATE.State flags
static const ULONG SID_FLAG_CHANGED				= 0x00000001;//the SID has changed
static const ULONG SID_FLAG_PRESENT				= 0x00000002;//the SID is indeed present
static const ULONG SID_FLAG_READONLY			= 0x00000004;//the source reports that the SID cannot be changed
static const ULONG SID_FLAG_DEFAULTED			= 0x00000008;//the SID comes from a default source
static const ULONG SID_FLAG_DEFAULT_AVAILABLE	= 0x00000010;//a default SID is available
static const ULONG SID_FLAG_MERGE_FULL_CTRL		= 0x00000020;//full auto-inh method control supported (i.e. SdMerge::MergeTreeEditState())
static const ULONG SID_FLAG_MERGE_CANON_CTRL	= 0x00000040;//canonical control, i.e. replace or no change
static const UCHAR SID_MERGE_MODE_SHIFT			= 0x10;
static const ULONG SID_MERGE_MODE_BITS			= 0x000F0000;
static const ULONG SID_MERGE_MODE_NONE			= 0x00000000;//don't do any merging
static const ULONG SID_MERGE_MODE_REPLACE		= 0x00010000;//replace children with this SID
static const ULONG SID_MERGE_MODE_MAX			= 0x00010000;

static const USHORT RMBITS_FLAG_CHANGED			= 0x0001;
static const USHORT RMBITS_FLAG_PRESENT			= 0x0002;

//SD_EDIT_STATE.State flags
static const ULONG SD_FLAG_SERVER_SECURITY		= 0x00000001;
static const ULONG SD_FLAG_MERGE_FULL_CTRL		= 0x00000002;//SD Edit will do the merging itself, so all merge features are available
static const ULONG SD_MERGE_ALL_OBJECTS			= 0x00000004;//merge all objects in tree, even if a noop is expected
static const ULONG SD_FLAG_CONTAINER			= 0x00000008;//object is a container (i.e. container inherit ACEs apply)
static const ULONG SD_FLAG_CONTAINERS_ONLY		= 0x00000010;//all objects are containers: only container (not object) inherit
static const ULONG SD_FLAG_OBJECT_SUPPORT		= 0x00000020;//supports object ACEs
static const ULONG SD_FLAG_NO_DELETE			= 0x00000040;//delete right not supported by object
static const ULONG SD_FLAG_NO_SYNCHRONIZE		= 0x00000080;//synchronize right not supported by object
static const ULONG SD_FLAG_LABEL_SUPPORT		= 0x00000100;//integrity labels are supported
static const ULONG SD_FLAG_LABEL_SET_ANY		= 0x00000200;//the integrity label can be changed to any value (not just <= caller's)

//although there exist many privileges, these are the ones relevant to object security
//synchronized with PrivUsePrivs
static const UCHAR PRIV_BACKUP		= 0x01;
static const UCHAR PRIV_RESTORE		= 0x02;
static const UCHAR PRIV_TAKE_OWN	= 0x04;
static const UCHAR PRIV_SECURITY	= 0x08;
static const UCHAR PRIV_RELABEL		= 0x10;

//sid categories as a bitmask
static const ULONG SID_TYPE_USER =			0x00000001;
static const ULONG SID_TYPE_GROUP =			0x00000002;
static const ULONG SID_TYPE_DOMAIN =		0x00000004;
static const ULONG SID_TYPE_ALIAS =			0x00000008;
static const ULONG SID_TYPE_WELL_KNOWN =	0x00000010;
static const ULONG SID_TYPE_DELETED =		0x00000020;
static const ULONG SID_TYPE_INVALID =		0x00000040;
static const ULONG SID_TYPE_UNKNOWN =		0x00000080;
static const ULONG SID_TYPE_COMPUTER =		0x00000100;
 
//option arrays
enum SdpValType
{
	SptOther,
	SptSubList,
	SptString,
	SptInt32,
	SptInt32Hex,
	SptBool,
	SptPresent, //same as bool, except false unless specified (note that such options are easier to specify but impossible to override)
	SptEnum,
	SptMultiEnumOr //same as enum, but with the option to specify multiple values at the same time ORed together
};

struct SDE_ENUM_VAL
{
	PCWSTR Name;
	ULONG_PTR Value;
};

struct SDE_ENUM
{
	ULONG ValCount;
	union
	{
		ULONG_PTR Choice;
		ULONG Choice32;
	};
	SDE_ENUM_VAL *Vals;
};

struct SDE_OPTS;

struct SDE_OPT
{
	PCWSTR Name;
	ULONG Flags; //bottom 16 bits are generic, top 16 reserved for option targets
	SdpValType Type;
	union
	{
		PVOID Void;
		SDE_OPTS *SubList;
		PCWSTR String; //note that SDE_OPT does not own this member's storage
		ULONG Int32;
		BOOL Bool;
		SDE_ENUM *Enum;
	};
};

static const UCHAR SDE_OPT_USER_LSHIFT = 16;

static const ULONG SDE_OPT_SET				= 0x00000001;
static const ULONG SDE_OPT_SPECIFIED		= 0x00000002;
static const ULONG SDE_OPT_DATA_OWNERSHIP	= 0x00000004; //the opt itself owns the data pointed to by the Void union, else data is owned elsewhere, guarenteed to be available (usually tied to the binary module's lifetime)

struct SDE_OPTS
{
	ULONG OptCount;
	SDE_OPT *Opts;
};

struct SDE_GENERIC_OPTS
{
	ULONG Length;
	PCWSTR ObjName;
	PCWSTR ObjType;
	PCWSTR ObjTypeClass;
	PCWSTR Host;
	PCWSTR Domain;
	BOOL CaseSensitiveSpecified;
	BOOL CaseSensitive;
};